 /*
* Species.h
*
*  Created on: Nov 14, 2009
*      Author: OD
*/

#ifndef SPECIES_H_
#define SPECIES_H_
#include <string>
#include <vector>
#include "Instruction.h"

/**
* contains non mutable information about a particular species
*/
class Species{
private:
       char myName;
       std::vector<Instruction> myInstructions;

public:
       Species(char name, std::vector<Instruction> instructions):
               myName (name),
               myInstructions (instructions){}

       char getName(){
               return myName;
       }
       Instruction getInstruction(int i){
               return myInstructions[i];
       }
       std::vector<Instruction>& getInstructions() {
		return myInstructions;
	}
       int getInstructionSize(){
               return myInstructions.size();//not working, just idea
       }

	//hop=0, infect=1, go=2, left=3, right=4, ifEmpty=5, ifEnemy=6, ifRandom=7, ifWall=8
	//array build is a bit wasteful. default constructs then initializes data
	static std::vector<Instruction>& getHopperInstruction(){
		static std::vector<Instruction> i(2);
		i[0].setOp(0);
		i[1].setOp(2);
		i[1].setStep(0);
		return i;
	}

	static std::vector<Instruction>& getFoodInstruction(){
		static std::vector<Instruction> i(2);
		i[0].setOp(3);
		i[1].setOp(2);
		i[1].setStep(0);
		return i;
	}

	static std::vector<Instruction>& getRoverInstruction(){
		/*
         	0: if_enemy 9
		1: if_empty 7
		2: if_random 5
		3: left
		4: go 0
		5: right
		6: go 0
		7: hop
		8: go 0
		9: infect
		10: go 0
		*/
		static std::vector<Instruction> i(11);
		i[0].setOp(6);
		i[0].setStep(9);
		i[1].setOp(5);
		i[1].setStep(7);
		i[2].setOp(7);
		i[2].setStep(5);
		i[3].setOp(3);
		i[4].setOp(2);
		i[4].setStep(0);
		i[5].setOp(4);
		i[6].setOp(2);
		i[6].setStep(0);
		i[7].setOp(0);
		i[8].setOp(2);
		i[8].setStep(0);
		i[9].setOp(1);
		i[10].setOp(2);
		i[10].setStep(0);
		return i;
	}

	static std::vector<Instruction>& getTrapInstruction(){
		 /*
		0: if_enemy 3
		1: left
		2: go 0
		3: infect
		4: go 0
		*/
		static std::vector<Instruction> i(5);
		i[0].setOp(6);
		i[0].setStep(3);
		i[1].setOp(3);
		i[2].setOp(2);
		i[2].setStep(0);
		i[3].setOp(1);
		i[4].setOp(2);
		i[4].setStep(0);
		return i;
	}
	
	static std::vector<Instruction>& getBestInstruction(){
		 /*
		0: if_enemy 4
		1: if_wall 6
		2: hop
		3: go 0
		4: infect
		5: go 0
		6: left    //hit one wall
		7: hop
		8: if_enemy 17
		9: if_wall 15
		10: ifempty 19  
		11: left   //back to ally
		12: left
		13: infect
		14: go 13
		15: left    //in corner
		16: go 13
		17: infect
		18: go 8
		19: hop
		20: go 8
		*/
		//hop=0, infect=1, go=2, left=3, right=4, ifEmpty=5, ifEnemy=6, ifRandom=7, ifWall=8
		static std::vector<Instruction> i(22);
		i[0].setOp(6);
		i[0].setStep(4);
		i[1].setOp(8);
		i[1].setStep(6);
		i[2].setOp(0);
		i[3].setOp(2);	
		i[3].setStep(0);
		i[4].setOp(1);
		i[5].setOp(2);
		i[5].setStep(0);
		i[6].setOp(4);
		i[7].setOp(1);
		i[8].setOp(2);
		i[8].setStep(7);
		/*
		i[0].setOp(6);
		i[0].setStep(4);
		i[1].setOp(8);
		i[1].setStep(6);
		i[2].setOp(0);
		i[3].setOp(2);	
		i[3].setStep(0);
		i[4].setOp(1);
		i[5].setOp(2);
		i[5].setStep(0);
		i[6].setOp(3);
		i[7].setOp(0);
		i[8].setOp(6);
		i[8].setStep(17);
		i[9].setOp(8);
		i[9].setStep(15);
		i[10].setOp(5);
		i[10].setStep(19);
		i[11].setOp(3);
		i[12].setOp(3);
		i[13].setOp(1);
		i[14].setOp(2);
		i[14].setStep(13);
		i[15].setOp(3);
		i[16].setOp(2);
		i[16].setStep(13);
		i[17].setOp(1);
		i[18].setOp(2);
		i[18].setStep(8);
		i[19].setOp(0);
		i[20].setOp(2);
		i[20].setStep(8);
		*/
		return i;
	}



       
};

#endif /* SPECIES_H_ */
 
